﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Gmantis.Controls.DataGrid
{
    internal class DataGridVisibleItems<T>
    {
        // Fields
        private int _firstVisibleItem;
        private Func<T, int> _index;
        private Func<T, bool> _isFrozen;
        private int _lastVisibleItem;
        private T[] _orderedVisibleItems;
        private List<T> _visibleItems;

        // Methods
        public DataGridVisibleItems(Func<T, int> index, Func<T, bool> isFrozen)
        {
            this._visibleItems = new List<T>();
            this._firstVisibleItem = -1;
            this._lastVisibleItem = -1;
            this._index = index;
            this._isFrozen = isFrozen;
        }

        internal void AddVisibleItem(T item)
        {
            this._orderedVisibleItems = null;
            this._visibleItems.Add(item);
            if (!this._isFrozen(item))
            {
                int num = this._index(item);
                this._firstVisibleItem = Math.Min(this._firstVisibleItem, num);
                this._lastVisibleItem = Math.Max(this._lastVisibleItem, num);
            }
        }

        internal void ClearVisibleItems()
        {
            this._orderedVisibleItems = null;
            this._visibleItems.Clear();
            this._firstVisibleItem = 0x7fffffff;
            this._lastVisibleItem = -2147483648;
        }

        internal int GetIndexFromItem(T item)
        {
            Comparer<T> comparer = new Comparer<T>
            {
                parent = (DataGridVisibleItems<T>)this
            };
            return Array.BinarySearch<T>(this.Items, item, comparer);
        }

        // Properties
        public int FirstVisibleItem
        {
            get
            {
                if ((this._firstVisibleItem >= 0) && (this._firstVisibleItem != 0x7fffffff))
                {
                    return this._firstVisibleItem;
                }
                return -1;
            }
        }

        public bool HasItems
        {
            get
            {
                return (this._visibleItems.Count > 0);
            }
        }

        public T[] Items
        {
            get
            {
                if (this._orderedVisibleItems == null)
                {
                    this._orderedVisibleItems = this._visibleItems.OrderBy<T, int>(this._index).ToArray<T>();
                }
                return this._orderedVisibleItems;
            }
        }

        public int LastVisibleItem
        {
            get
            {
                if (this._lastVisibleItem < 0)
                {
                    return -1;
                }
                return this._lastVisibleItem;
            }
        }

        // Nested Types
        private class Comparer<T> : IComparer<T>
        {
            // Fields
            public DataGridVisibleItems<T> parent;

            // Methods
            public int Compare(T x, T y)
            {
                return this.parent._index(x).CompareTo(this.parent._index(y));
            }
        }
    }
}
